/*
 * Copyright 2009 Millibit Systems.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package jp.millibit.fiber
{
	import flash.events.Event;
	import flash.events.EventDispatcher;
	
	import jp.millibit.core.ObjectEvent;
	import jp.millibit.core.assert;

	public final dynamic class Execution
	{

		private var _fiber:Fiber;

		private var _length:uint;

		private static var _creation:Boolean;

		internal static const ERROR:String = "error";

		internal static const COMPLETE:String = "complete";

		internal static const CALLBACK:String = "callback";

		internal var dispatcher:EventDispatcher;

		internal static function create(fiber:Fiber, args:Array):Execution
		{
			_creation = true;
			var exec:Execution = new Execution(fiber, args);
			_creation = false;

			return exec;
		}

		public function Execution(fiber:Fiber, args:Array)
		{
			assert(_creation, "Unsupported.");

			_fiber = fiber;
			_length = args === null ? 0 : args.length;
			dispatcher = new EventDispatcher();

			if (length > 0)
			{
				for (var i:int = 0, len:uint = args.length; i < len; i++)
				{
					this[i] = args[i];
				}
			}
		}

		public function get fiber():Fiber
		{
			return _fiber;
		}

		public function get length():uint
		{
			return _length;
		}

		public function callback(value:Object):void
		{
			dispatcher.dispatchEvent(new ObjectEvent(CALLBACK, value));
		}

		public function error(e:*):void
		{
			dispatcher.dispatchEvent(new ObjectEvent(ERROR, e));
		}

		public function complete():void
		{
			dispatcher.dispatchEvent(new Event(COMPLETE));
			_fiber.complete();
		}
	}
}
